JavaScript - 1 基础语法

原型链

创建对象有几种方法

1
2
3
4
5
6
7
8
9
// 1.字面量对象方式
var o1={name:'o1'};
var 02=new Object{name:'o2'};
// 2.通过构造函数
var M=function(name){this.name=name};
var o3=new M('o3');
// 3.Onject.create
var p={name:'p'};
var o4=Object.create(p);

原型、构造函数、实例、原型链

原型、构造函数、实例

image-20190421165005752

1
2
3
4
5
6
7
// M是构造函数,o3是 实例
var M=function(name){this.name=name};
var o3=new M('o3');

M.prototype.constructor===M //true
o3.__proto__==M.prototype //true
M.__proto__==Fuction.prototype //true,M为Fuction构造函数的实例,原型对象相同

原型对象和原型链的作用

原型对象作用:构造函数中增加了很多属性和方法,实例可以共用。多个实例的时候,想使用这个方法的时候,不能每个实例都取拷贝一份。可以考虑存在一个共同的地方——原型对象。

1
2
3
4
5
6
7
// 原型链的方式找到原型对象,原型对象的方法是被不同的实例所共有的。
var M=function(name){this.name=name};
var o3=new M('o3');
M.prototype.say=function(){
console.log('say hi');
}
var o5=new M('o5');

原型链的作用:实例调用方法时没有找到方法时,如则通过 proto 在上级对象去找,再没找到的时候,则继续找,直至Object.prototype根部。

instanceof的原理

image-20190421171830966

判断实例对象的 proto 和生成其的构造函数的prototype是不是引用同一个地址。(ps.实例的instanceof在比较的时候,与原型链上想上找的构造函数相比都是true。)

new运算符

JavaScript作用域和闭包

变量提升

js会把所有的声明提到前面,然后再顺序执行赋值等其它操作,因为在打印a之前已经存在a这个变量了,只是没有赋值,所以会打印出undefined,为不是报错,fn同理。

作用域

JavaScript是没有块级作用域的:if里的变量都可以访问

js有全局作用域和函数作用域:在函数里声明的变量,在是不会影响外面的变量的,看结果

作用域链:一个自由变量,js引擎在执行到console.log(x)时,会先在F2中寻找x,没找到就去当前作用域的父级作用域F1中找,还找不到就在往上找直到全局作用域。

闭包

Javascript允许使用内部函数—即函数定义和函数表达式位于另一个函数的函数体内。而且,这些内部函数可以访问它们所在的外部函数中声明的所有局部变量、参数和声明的其他内部函数。当其中一个这样的内部函数在包含它们的外部函数之外被调用时,就会形成闭包。

其应用

我们有时候需要得到函数内的局部变量。但是,前面已经说过了,正常情况下,这是办不到的,只有通过变通方法才能实现。

那就是在函数的内部,再定义一个函数,然后把这个函数返回。

在本例中就实现了闭包,简单的说,闭包就是能够读取其他函数内部变量的函数。

1
2
3
4
5
6
7
8
9
10
11
function F1(){
var a = 100
//返回一个函数 (函数作为返回值)
return function (){
console.log(a)
}
}
//f1得到一个函数
var f1 = F1()
var a = 200
f1()

JS-web-API

6-5 Ajax跨域

手写ajax:使用API——XMLHttpRequest()实现ajax

1
2
3
4
5
6
7
8
9
10
11
var xhr = new XMLHttpRequest()
xhr.open("GRT","/api",false)
xhr.onreadystatechange = function(){
// 异步函数执行,可以参考JS基础中的异步模块
if(xhr.readyState == 4){
if(xhr.status == 200){
alert(xhr.responseText)
}
}
}
xhr.send(null)

什么是跨域?

浏览器的通远策略,不允许ajax访问其他域的接口。前端用JSONP,后端用http header。

跨域条件:

协议、域名、端口,有一个不同就算跨域

三个标签允许跨域加载资源:

  • 1图片:< img src=xxx> 、打点统计,统计网站可能是其他域:可以跨域;兼容多个浏览器
  • 2CSS,外部样式表的位置: < link href=xxx>、3地址,引入外部js文件,外部脚本文件的 URL:< script src=xxx>:可以使用CDN,CDN也是其他域。

注意

所有跨域请求都必须经过信息方允许;若未经允许即可获取,就是浏览器同源策略出现了问题。eg.知乎日报的API

JSONP:简单

非官方跨域数据交互协议
原理:为了减轻web服务器的负载,我们把js、css,img等静态资源分离到另一台独立域名的服务器上,在html页面中再通过相应的标签从不同域名下加载静态资源,而被浏览器允许。
方法:可以通过动态创建script,再请求一个带参网址实现跨域通信。
缺点:只能实现get一种请求

  • 例如自己的网站需要访问一个慕课网的接口
  • 慕课给我一个地址 https://coding.imooc.com/api.js
  • 返回内容格式如callback({x:100,y:200}) 可动态生成:
    • callback相当于执行的函数
    • 函数的参数:为内容
1
2
3
4
5
6
<script>
window.callback = function(data){
console.log(data)//输出跨域的信息
}
</script>
<script src="https://coding.imooc.com/api.js"></script>

跨域资源共享(CORS):复杂

主流的跨域解决方案。

普通跨域请求:只服务端设置http header{Access-Control-Allow-Origin}即可,前端无须设置。

若要带cookie请求:前后端都需要设置。

1
2
//前端设置 原生JS
xhr.withCredentials = true;

窗口之间JS跨域postMessage

用法:postMessage(data,origin)方法接受两个参数
data: html5规范支持任意基本类型或可复制的对象,但部分浏览器只支持字符串,所以传参时最好用JSON.stringify()序列化。
origin: 协议+主机+端口号,也可以设置为”*”,表示可以传递给任意窗口,如果要指定和当前窗口同源的话设置为”/“。

6-6 存储

本身用于客户端和服务端通信
本身有本地存储功能,于是被”借用”
document.cookie = xxx 获取和修改即可

缺点:

存储量太小,4kb;所有http都会带着,影响获取资源的效率(因此仅4kb);API简单,需要封装才能用 document.cookie

localStorage和sessionStorage

HTML5存储设计,容量5M
API简单易用:localStorage.setItem(key,value)localStorage.getItem(key)
注意:应该try-catch封装,在iOS无痕模式下,getItem(key)会报错

区别:

容量不同
是否会被携带到ajax
API易用性
清除:localStorage浏览器不主动清除数据,非登录状态都存在这里;sessionStorage每次会话结束会清清除。

第七章 7开发环境

7-3 git常用命令

代码管理、大型项目需要多人协作开发

命令:

1
git add

第1章 系好安全带,准备启航

第2章 你要懂的规则(JS基础语法)

第3章 一起组团(数组)

第4章 跟着我的节奏走(流程控制语句)

第5章 小程序,大作用(函数)

第6章 事件响应,让网页交互

第7章 JavaScript内置对象

第8章 浏览器对象

第9章 DOM对象,控制HTML元素

第10章 编程挑战

###